var data = [
    { value: '周杰伦听妈妈的话，好好听！', time: 5, color: 'red', speed: 1, fontSize: 22 },
    { value: '快快长大吧，才能保护她', time: 10, color: '#00a1f5', speed: 1, fontSize: 30 },
    { value: '听妈妈的话，晚点再恋爱吧', time: 6 },
    { value: '快快长大吧', time: 20, color: '#fff', speed: 0.5, fontSize: 20 },
    { value: '我很喜欢周董', time: 15, color: 'blue', speed: 2, fontSize: 26 },
  ]
  
  var canvas = document.getElementById('canvas')
  var video = document.getElementById('video')
  var $txt = document.getElementById('text')
  var $btn = document.getElementById('btn')
  var $color = document.getElementById('color')
  var $range = document.getElementById('range')
  
  
  // 创建CanvasBarrage 类  舞台的搭建
  class CanvasBarrage {
    constructor (canvas, video, opts = {}) { // 定义一个构造函数
      if (!canvas || !video) return 
  
      // 将传进来的参数挂在当前函数上
      this.video = video
      this.canvas = canvas
      // 设置canvas画布的宽高和video保持一致
      this.canvas.width = video.width
      this.canvas.height = video.height
  
      // 创建一个画布
      this.ctx = canvas.getContext('2d')
      // console.log(this.ctx);
  
      // 设置默认的弹幕样式，如果没传，就启用默认
      let defOpt = {
        color: '#e91e63',
        speed: 1,
        opacity: 0.5,
        fontSize: 20,
        data: []
      }
      Object.assign(this, defOpt, opts)
  
      // 判断视屏是播放还是暂停状态, 默认true为暂停
      this.isPaused = true
      // 得到所有的弹幕消息
      this.barrages = this.data.map((item) => {  // barrages里面现在装的就是一个数组，该数组里面存放了所有已经被初始化好了的弹幕
        return new Barrage(item, this)
      })
    }
  
    // 渲染canvas绘制的弹幕
    render () {
      // 渲染的第一步，是清除原来的画布
      this.clear()
      // 渲染弹幕
      this.renderBarrage()
      if (this.isPaused === false) {
        // 递归的渲染弹幕
        requestAnimationFrame(this.render.bind(this))
      }
    }
  
    clear () {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)
    }
  
    renderBarrage () {
      // 首先拿到视频播放的时间，根据播放的时间来判断当前弹幕是否出现
      let time = this.video.currentTime
  
      // 循环遍历所有的弹幕
      this.barrages.forEach(barrage => {
        if (time >= barrage.time && !barrage.flag) {
  
          // 判断当前弹幕已经初始化好了
          if (!barrage.isInit) {
            barrage.init()
            barrage.isInit = true
          }
  
          // 弹幕是要从右往左渲染，所以不断的让弹幕x轴坐标变小就可以了
          barrage.x -= barrage.speed
          barrage.render()
  
          if (barrage.x < -barrage.width) {
            barrage.flag = true // flag 为 true 意味着弹幕走出了屏幕
          }
        }
      });
    }
  
    add (obj) {
      this.barrages.push(new Barrage(obj, this))
    }
  }
  
  
  
  // 创建一个Barrage类，用来实例化每一条弹幕
  class Barrage {
    constructor (obj, ctx) {
      this.value = obj.value // 弹幕的内容
      this.time = obj.time // 弹幕出现的时间
      this.obj = obj 
      this.context = ctx
    }
    // 初始化一条弹幕
    init () {
      this.color = this.obj.color || this.context.color
      this.speed = this.obj.speed || this.context.speed
      this.opacity = this.obj.opacity || this.context.opacity
      this.fontSize = this.obj.fontSize || this.context.fontSize
  
      // 计算每条弹幕的宽度
      let p = document.createElement('p')
      p.style.fontSize = this.fontSize + 'px'
      p.innerHTML = this.value
      document.body.appendChild(p)
      this.width = p.clientWidth
      document.body.removeChild(p)
  
      // 设置弹幕出现的位置
      this.x = this.context.canvas.width
      this.y = this.context.canvas.height * Math.random()
  
      // 做超出范围的处理
      if (this.y < this.fontSize) {
        this.y = this.fontSize
      } else if (this.y > this.context.canvas.height - this.fontSize) {
        this.y =  this.context.canvas.height - this.fontSize
      }    
    }
    // 让每一条弹幕出现在画布上
    render() {
      // 设置画布字体大小和字号
      this.context.ctx.font = `${this.fontSize}px Arial`
      // 设置画布字体颜色
      this.context.ctx.fillStyle = this.color
      // 绘制出文字
      this.context.ctx.fillText(this.value, this.x, this.y)
    }
  }
  
  
  let canvasBarrage = new CanvasBarrage(canvas, video, { data })
  video.addEventListener('play', () => {
    canvasBarrage.isPaused = false
    canvasBarrage.render()
  })
  
  
  $btn.addEventListener('click', () => {
    let value = $txt.value
    let time = video.currentTime
    let color = $color.value
    let fontSize = $range.value
  
    let obj = { value, time, color, fontSize }
    canvasBarrage.add(obj)
    $txt.value = ''
  })